<?php
/**
 * Created by PhpStorm.
 * User: Administrator
 * Date: 2024/4/10
 * Time: 12:01
 */

namespace plugin\admin\app\logic\plan;


use app\common\lib\Common;
use app\exception\IndexException;
use plugin\admin\app\exception\AdminException;
use plugin\admin\app\logic\BaseLogic;
use plugin\admin\app\model\image\ImageModelModel;
use plugin\admin\app\model\image\ImageModelRolaModel;
use plugin\admin\app\model\novel\NovelChapterPartModel;
use plugin\admin\app\model\novel\NovelPlanRoleModel;
use plugin\admin\app\model\plan\PlanRoleTagModel;
use plugin\admin\app\model\plan\PromotionPlanModel;
use support\Request;
use support\Response;

class RoleLogic extends BaseLogic
{
    protected static $instance;

    public function __construct()
    {
        $this->model = new NovelPlanRoleModel();
    }

    public static function getInstance()
    {
        //        if(is_object(self::$instance)){
//            return self::$instance;
//        }

        return new self();
    }

    public function select(Request $request): Response
    {
        $field = $request->input('field');
        if($field==false){
            $request->inputSet('field','created_at');
            $request->inputSet('order','desc');
        }

        $request->inputSet('isdel','0');
        return parent::select($request);
    }

    protected function formatNormal($items, $total): Response
    {
        $planMap = $this->getListMapById(PromotionPlanModel::getInstance(),$items,'planid','id');
        foreach($items as &$val){
            $val['planname'] = isset($planMap[$val['planid']])?$planMap[$val['planid']]['name']:$val['planid'];
            //$val['select_tag'] = !empty($val['select_tag'])?json_decode($val['select_tag'], true):[];
        }
        return parent::formatNormal($items, $total);
    }

    public function insert(Request $request): Response
    {
        if(empty($request->input('name'))){
            throw new AdminException(4020,'角色名称不能为空');
        }
        if(empty($request->input('ai_images'))){
            throw new AdminException(4020,'浏览图像不能为空');
        }
        if(empty($request->input('analyze_content'))){
            throw new AdminException(4020,'中文描述不能为空');
        }
        if(empty($request->input('prompt'))){
            throw new AdminException(4020,'英文描述不能为空');
        }
        if(empty($request->input('rolaid'))){
            throw new AdminException(4020,'Rola必选');
        }else{
            $rola = ImageModelRolaModel::getInstance()->find($request->input('rolaid'));
            $request->inputSet('rola',$rola['rola']);
        }

        return parent::insert($request);
    }


    protected function doInsert($data)
    {
        $id = parent::doInsert($data);
        $this->matchPartRole($id,$data['planid']);
    }

    public function update(Request $request): Response
    {
        if(empty($request->input('name'))){
            throw new AdminException(4020,'角色名称不能为空');
        }
        if(empty($request->input('ai_images'))){
            throw new AdminException(4020,'浏览图像不能为空');
        }
        if(empty($request->input('analyze_content'))){
            throw new AdminException(4020,'中文描述不能为空');
        }
        if(empty($request->input('prompt'))){
            throw new AdminException(4020,'英文描述不能为空');
        }
        if(empty($request->input('rolaid'))){
            throw new AdminException(4020,'Rola必选');
        }else{
            $rola = ImageModelRolaModel::getInstance()->find($request->input('rolaid'));
            $request->inputSet('rola',$rola['rola']);
        }
        return parent::update($request);
    }

    protected function doUpdate($id, $data)
    {
        parent::doUpdate($id,$data);
        $this->matchPartRole($id,$data['planid']);
    }

    public function delete(Request $request): Response
    {
        return parent::isDelete($request);
    }

    public function generatedPrompt(Request $request): Response
    {
        if(empty($request->input('analyze_content'))){
            throw new AdminException(4020,'中文描述词不能为空');
        }
        if(!empty($request->input('prompt_ai_command'))){
            $content = str_replace(['@content'],[$request->input('analyze_content')],$request->input('prompt_ai_command'));
        }else{
            $content = $request->input('analyze_content');
        }
        //var_dump($content);

        //todo 1 获取描述词
        $prompt = Common::generatedImagePrompt($content);
        if($request->input('type')=='regenerate_prompt'){
            return $this->json('0','ok',['data'=>$prompt]);
        }
    }

    public function generatedImage(Request $request): Response
    {
        $id = $request->input('id',0);
        $planid = $request->input('planid',0);
        $rolaid = $request->input('rolaid',0);

        $plan = PromotionPlanModel::getInstance()->getWhere(['id'=>$planid])->first();
        if($plan==false){
            throw new AdminException(4020,'方案不存在');
        }
        $aiImageCommands = json_decode($plan['ai_image_command'], true);
        if($aiImageCommands==false){
            throw new AdminException(4020,'生图指令JSON格式错误');
        }
        $modelVal = $aiImageCommands['override_settings']['sd_model_checkpoint']??'';
        if($modelVal==false){
            throw new AdminException(4020,'模型不能为空');
        }

//        $model = ImageModelModel::getInstance()->getWhere(['id'=>$plan['modelid']])->first();
//        if(empty($model)){
//            throw new AdminException(4020,'当前方案下没有模型');
//        }

        $rola = ImageModelRolaModel::getInstance()->getWhere(['id'=>$rolaid])->first();
        if(empty($rola)){
            throw new AdminException(4020,'Rola必选');
        }
        $nums = $request->input('nums','1');

        if(empty($request->input('prompt'))){
            throw new AdminException(4020,'英文描述词不能为空');
        }
        if(empty($request->input('ai_image_command'))){
            throw new AdminException(4020,'生成图像指令不能为空');
        }
        $prompt = $request->input('prompt');
        $sex = $request->input('sex',2);
        $prompt = $sex==2?'1 gril,'.$prompt:'1 boy,'.$prompt;
        $prompt .= ',<lora:'.$rola['rola'].':1>';

        $aiImageCommand = $request->input('ai_image_command');
        $aiImageCommands = json_decode($aiImageCommand, true);
        if($aiImageCommands==false){
            throw new AdminException(4020,'图像指令JSON格式错误');
        }
        $aiImageCommand = str_replace(['@model'],[$modelVal],$aiImageCommand);
        $requestId = Common::generatedAIImageByTemplate($aiImageCommand,$prompt,$modelVal,['batch_size'=>$nums],'admin_plan_role_image_view_'.$id);

        return $this->json(0,'ok',['requestid'=>$requestId]);
    }

    public function aiRegenerate(Request $request): Response
    {
        if($request->input('type')=='regenerate_prompt'){
            return $this->generatedPrompt($request);
        }elseif($request->input('type')=='regenerate_image'){
            return $this->generatedImage($request);
        }
    }

    protected function matchPartRole($id,$planid)
    {
        $role = NovelPlanRoleModel::getInstance()->find($id);
        if($role==false){
            return false;
        }
        $parts = NovelChapterPartModel::getInstance()->getWhere(['planid'=>$planid,'isdel'=>0])
                                                     ->orderBy('batch','desc')->orderBy('number','asc')->get();
        foreach ($parts as $part){
            if(mb_strpos($part['content'],$role['name'])!==false){
                $roleIds = $part['roleids'] ? json_decode($part['roleids'],true) : [];
                $roleIds = is_array($roleIds) ? $roleIds : [];
                array_push($roleIds,(string)$role['id']);
                $part['roleids'] = json_encode(array_unique($roleIds));
                $part->save();
            }
        }
    }

    public function selectTagList(Request $request): Response
    {
        $data = PlanRoleTagModel::getInstance()->getWhere(['status'=>1,'isdel'=>0])->orderBy('level1_name','asc')->get();

        $rows = [];
        foreach($data as $val){
            $rows[$val['level1_name']][$val['level2_name']][] = ['zh'=>$val['name'],'en'=>$val['en_name']];
        }

        return $this->json(0,'ok',$rows);
    }
}